package com.koomii.common.file.impl;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.koomii.common.file.FileStore;
import com.koomii.common.file.FileType;
import com.koomii.common.file.util.FileMD5;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;

import javax.activation.MimetypesFileTypeMap;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Date;

/**
 * Created with IntelliJ IDEA.
 * User: Greey
 * Date: 15-1-8
 * Time: 下午3:18
 * To change this template use File | Settings | File Templates.
 */
public class OSSFileStoreImpl implements InitializingBean,FileStore {
    private final static Log log = LogFactory.getLog(OSSFileStoreImpl.class);
    private String imgBucketName = "dxh-img";
    private String fileBucketName = "dxh-file";
    private String endPoint = "http://oss-cn-beijing.aliyuncs.com";
    private String keyId="XxR6Bh2R0crJJGj2";
    private String keySecret="UYr5eCFvNx8Sy4ZjvI8uMRUp7FrQGK";
    private OSSClient ossClient;

    @Override
    public String saveFile(File file,int fileType,String newName) {
        if(file==null || StringUtils.isEmpty(newName)){
            log.error("save file failed,file is null,or newName is Empty");
            return "";
        }
        String md5 = FileMD5.getFileMD5(file);
        log.debug("local md5="+md5);
        //根据不同的类型 存储
        MimetypesFileTypeMap mf = new MimetypesFileTypeMap();
        String contentType = mf.getContentType(file.getName());
        //上传文件的扩展名
        String oExt = FilenameUtils.getExtension(file.getName());
        //校验新文件名是否带扩展名
        String nExt = FilenameUtils.getExtension(newName);
        if(StringUtils.isNotEmpty(oExt) && StringUtils.isEmpty(nExt)){
            //原文件有扩展名  新文件名无扩展名  需要将新文件加上扩展名
            newName = newName + "."+oExt;
        }
        String str = null;
        //文件存储名称前加日期文件夹
        String newFilePath = getNewFilePath(newName,fileType);
        String bucketName = getBucketByFileType(fileType);
        try {
            str = uploadFile(file,contentType,newFilePath,bucketName);
            log.debug("oss md5="+str);
            if(!md5.equalsIgnoreCase(str)){
                log.error("oss return etag not equals the md5 value of local,fileName="+file.getName());
            }else{
                log.debug("------- same md5");
            }
        } catch (Exception e) {
            log.error("upload file to oss error,fileName="+file.getName(),e);
            return "";
        }
        return newFilePath;
    }
    // 文件目录存储规划:  文件类型/日期/文件
    private static String getNewFilePath(String newName, int fileType) {
        String dir = "";
        switch (fileType){
            case FileType.IMAGE:break;
            case FileType.UPGRADE_PACK:dir="pack";break;
            case FileType.ATTACHED_FILE:dir="attach";break;
        }
        if(StringUtils.isNotEmpty(dir)){
            return dir + "/" +DateFormatUtils.format(new Date(), "yyyyMMdd")+"/"+newName;
        }
        return DateFormatUtils.format(new Date(), "yyyyMMdd")+"/"+newName;
    }

    @Override
    public boolean deleteFile(String path,int fileType) {
        String bucketName = getBucketByFileType(fileType);
        //根据不同的类型删除
        try {
            ossClient.deleteObject(bucketName,path);
        } catch (Exception e) {
            log.error("delete oss file error,file="+path,e);
            return false;
        }
        return true;
    }

    private String getBucketByFileType(int fileType) {
        if(FileType.IMAGE==fileType){
            return imgBucketName;
        }
        return fileBucketName;
    }

    private String uploadFile(File file,String fileType,String newName,String bucketName)
            throws OSSException, ClientException, FileNotFoundException {
        ObjectMetadata objectMeta = new ObjectMetadata();
        objectMeta.setContentLength(file.length());
        if(StringUtils.isNotEmpty(fileType)){
            //标记文件类型
            objectMeta.setContentType(fileType);
        }
        InputStream input = new FileInputStream(file);
        PutObjectResult pr = ossClient.putObject(bucketName, newName, input, objectMeta);
        return pr.getETag();
    }

    // 把Bucket设置为所有人可读
    private void createBucketPublicReadable(OSSClient client, String bucketName)
            throws OSSException, ClientException {
        //创建bucket
        client.createBucket(bucketName);
        //设置bucket的访问权限，public-read权限
        client.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        if(StringUtils.isEmpty(keyId) || StringUtils.isEmpty(keySecret)){
            log.error("oss unusable,keyId or keySecret is null");
        } else{
            try {
                ossClient = new OSSClient(endPoint,keyId,keySecret);
                if(ossClient!=null){
                    // 初始化 两个 Bucket
                    //判断 图片存储的 Bucket 是否存在  若不存在 创建  并设置公共读的权限
                    boolean exist = ossClient.doesBucketExist(imgBucketName);
                    if(!exist){
                        log.error("create new buckets,name="+imgBucketName);
                        createBucketPublicReadable(ossClient,imgBucketName);
                    }
                    //判断 文件存储的 Bucket 是否存在  若不存在 创建  并设置公共读的权限
                    boolean ex = ossClient.doesBucketExist(fileBucketName);
                    if(!ex){
                        log.error("create new buckets,name="+fileBucketName);
                        createBucketPublicReadable(ossClient,fileBucketName);
                    }
                    log.error("init ossClient success!");
                }else{
                    log.error("init ossClient failed!");
                }
            } catch (Exception e) {
                log.error("init ossClient exception",e);
            }
        }

    }


    public void setImgBucketName(String imgBucketName) {
        this.imgBucketName = imgBucketName;
    }

    public void setFileBucketName(String fileBucketName) {
        this.fileBucketName = fileBucketName;
    }

    public void setEndPoint(String endPoint) {
        this.endPoint = endPoint;
    }

    public void setKeyId(String keyId) {
        this.keyId = keyId;
    }

    public void setKeySecret(String keySecret) {
        this.keySecret = keySecret;
    }

    public static void main(String[] args){
        System.out.println(FilenameUtils.getExtension("sssss.dsfsdferer.dsgsd.sdfsd.dsfsd111"));
    }
}
